<?php

namespace services\buss;

use api\modules\common\services\UploadService;
use api\modules\v1\forms\buss\ContentForm;
use api\modules\v1\forms\buss\ContentPublishRecordForm;
use common\components\Service;
use common\helpers\CommonHelper;
use common\helpers\DateHelper;
use common\helpers\RedisHelper;
use common\models\base\CommonStatus;
use common\models\base\Department;
use common\models\base\Tags;
use common\models\buss\Accounts;
use common\models\buss\Content;
use common\models\buss\ContentPublishRecord;
use common\models\buss\Doctors;
use common\models\buss\Platform;
use common\models\log\LogMemberOp;
use common\models\member\Member;
use common\models\sys\SysFile;
use services\base\CommonRelationService;
use services\base\CommonStatusService;
use services\base\DepartmentService;
use services\base\TagsService;
use services\log\LogMemberOpService;
use services\member\MemberService;
use services\sys\SysFileService;
use Yii;
use yii\db\Expression;

/**
 * Class ContentPublishRecordService
 * @package services\buss
 */
class ContentPublishRecordService extends Service
{
    /**
     * 发布内容列表
     * @param array $params
     * @param int $page
     * @param int $pageSize
     * @return array
     */
    public function getListPage(array $params = [], int $page = 0, int $pageSize = 0): array
    {
        $query = ContentPublishRecord::find()->alias('cpr')
            ->select([
                'cpr.*',
                'c.title',
                'd.name doctor_name',
                'a.nickname account_name',
                'a.platform_id',
                'a.department_id',
//                'dp.department_name'
            ])
            ->innerJoin(Content::tableName().' c', 'cpr.content_id = c.id')
            ->leftJoin(Doctors::tableName().' d', 'cpr.doctor_id = d.id')
            ->leftJoin(Accounts::tableName().' a', 'cpr.account_id = a.id')
            /*->leftJoin(Department::tableName() . ' dp', 'dp.id = a.department_id and dp.status in ('.Department::STATUS_ENABLE.','. Department::STATUS_INVALID.')')*/
            ->where([
                'c.status' => Content::STATUS_ENABLE,
                'cpr.status' => ContentPublishRecord::STATUS_ENABLE
            ]);

        // 权限【项目、部门】
        $memberAuth = MemberService::getLoginMemberLimit();
        // 是超管直接跳过
        if ($memberAuth['super_type'] != Member::SUPER_TYPE_SUPER_ADMIN) {
            // 是否为项目管理员
            if ($memberAuth['admin_project_ids']) {
                $query->andWhere([
                    'or',
                    ['a.project_id' => $memberAuth['admin_project_ids']],// 是【一个或几个】项目管理员则查全项目数据
                    [
                        'a.department_id' => $memberAuth['all_department_ids'],
                        'a.project_id' => $memberAuth['member_project_ids'],
                        'a.use_mid' => $memberAuth['all_member_ids'],
                    ]
                ]);
            } else {
                $query->andWhere([
                    'a.department_id' => $memberAuth['all_department_ids'],
                    'a.project_id' => $memberAuth['member_project_ids'],
                    'a.use_mid' => $memberAuth['all_member_ids'],
                ]);
            }
        }

        // 部门
        if (isset($params['department_id']) && $params['department_id']) {
            $allIds = $params['department_id'];
            $department = RedisHelper::getDepartment($params['department_id']);
            if ($department->data_level == Department::DATA_LEVEL_DEPARTMENT_ALL) {
                $childDepartmentList = DepartmentService::getChildDepartmentList($department->tree_id);
                $allIds = array_merge([$department->id], array_column($childDepartmentList, 'id'));
            }
            $query->andWhere(['a.department_id' => $allIds]);
        }
        if (isset($params['content_id']) && $params['content_id']) {
            $query->andWhere(['cpr.content_id' => $params['content_id']]);
        }
        if (isset($params['publish_stime']) && $params['publish_stime']) {
            $query->andWhere(['>=', 'cpr.publish_time', strtotime($params['publish_stime'])]);
        }
        if (isset($params['publish_etime']) && $params['publish_etime']) {
            $query->andWhere(['<=', 'cpr.publish_time', strtotime($params['publish_etime'].' 23:59:59')]);
        }
        if (isset($params['keywords']) && $params['keywords']) {
            $query->andWhere(['like', 'c.title', $params['keywords']]);
        }
        if (isset($params['platform_id']) && $params['platform_id']) {
            $query->andWhere(['a.platform_id' => $params['platform_id']]);
        }
        if (isset($params['doctor_id']) && $params['doctor_id']) {
            $query->andWhere(['cpr.doctor_id' => $params['doctor_id']]);
        }
        if (isset($params['created_member_id']) && $params['created_member_id']) {
            $query->andWhere(['cpr.created_member_id' => $params['created_member_id']]);
        }
        // 排序
        if (isset($params['order_column']) && $params['order_column']) {
            $sort = isset($params['order_sort']) && $params['order_sort'] == 'asc' ? SORT_ASC : SORT_DESC;
            switch ($params['order_column']) {
                case 'read_num':
                case 'like_num':
                case 'collect_num':
                case 'comment_num':
                case 'publish_time':
                case 'change_date':
                    $order["cpr.{$params['order_column']}"] = $sort;
                    break;
                default :
                    break;
            }
            $order && $order['cpr.id'] = SORT_DESC;
        }
        empty($order) && $order = ['cpr.publish_time' => SORT_DESC, 'cpr.id' => SORT_DESC];

        return $this->getListPageRes($query, $page, $pageSize, $order);
    }

    /**
     * 格式化列表
     * @param array $data
     * @return array
     */
    public function getListPageFormat(array $data = []): array
    {
        // 是否编辑
        $logList = LogMemberOpService::getLogMemberOpListExist(LogMemberOp::TYPE_CONTENT_PUBLISH_UPDATE_DATA, array_column($data, 'id'));
        $list = [];
        foreach ($data as $row) {
            $departmentName = DepartmentService::getParent($row['department_id']);
            $list[] = [
                'id' => $row['id'],
                'content_id' => $row['content_id'],
                'title' => $row['title'],
                'platform_name' => RedisHelper::getPlatform((int)$row['platform_id'])->name ?? '',
                'account_name' => $row['account_name'] ?: '',
                'doctor_name' => $row['doctor_name'] ?: '',
//                'department_name' => $row['department_name'] ?: '',
                'department_name' => implode(' / ', $departmentName),
                'read_num' => CommonHelper::getNumFormat($row['read_num']),
                'like_num' => CommonHelper::getNumFormat($row['like_num']),
                'collect_num' => CommonHelper::getNumFormat($row['collect_num']),
                'comment_num' => CommonHelper::getNumFormat($row['comment_num']),
                'created_member_name' => RedisHelper::getMember($row['created_member_id'])->realname ?? '',
                'publish_time_str' => DateHelper::timestampToDate($row['publish_time'], DateHelper::DATE_FORMAT_4),
                'change_date' => DateHelper::timestampToDate(strtotime($row['change_date']), DateHelper::DATE_FORMAT_4),
                'is_edit' => isset($logList[$row['id']]) ? 1 : 0,
            ];
        }
        return $list;
    }

    /**
     * 获取内容创建人IDs
     * @return array
     */
    public static function getCreateMemberIds(): array
    {
        return ContentPublishRecord::find()
            ->select(['created_member_id'])
            ->column();
    }

    /**
     * 状态下拉筛选项
     * @return array[]
     */
    public static function getPublishStatusCondition(): array
    {
        return [
            ['value' => Content::PUBLISH_STATUS_ON, 'label' => Content::$publishStatuss[Content::PUBLISH_STATUS_ON]],
            ['value' => Content::PUBLISH_STATUS_OFF, 'label' => Content::$publishStatuss[Content::PUBLISH_STATUS_OFF]],
        ];
    }

    /**
     * 操作人列表
     * @return array
     */
    public static function getCreatedMemberList(): array
    {
        $ids = self::getCreateMemberIds();
        return $ids ? MemberService::getListCondition($ids) : [];
    }

    /**
     * 列表筛选项
     * @return array
     */
    public function getSelectCondition(): array
    {
        return [
            'platform' => PlatformService::getListCondition(),
            'doctor' => DoctorsService::getListCondition(),
            'created_member' => self::getCreatedMemberList(),
            'department_arr' => MemberService::getMemberDepartmentCondition()['list'],
        ];
    }

    /**
     * 发布内容详情
     * @param array $params
     * @return array
     */
    public function getInfo(int $id): array
    {
        $data = [];
        // 内容信息
        $contentPublishRecord = ContentPublishRecord::findOne($id);
        if ($contentPublishRecord) {
            $data = [
                'id' => $contentPublishRecord->id,
                'read_num' => CommonHelper::getNumFormat($contentPublishRecord->read_num),
                'like_num' => CommonHelper::getNumFormat($contentPublishRecord->like_num),
                'collect_num' => CommonHelper::getNumFormat($contentPublishRecord->collect_num),
                'comment_num' => CommonHelper::getNumFormat($contentPublishRecord->comment_num),
            ];
        }
        return $data;
    }

    /**
     * 统计内容发布数据
     * @param int|array $contentIds
     * @return array
     */
    public static function statisticNumData($contentIds): array
    {
        return ContentPublishRecord::find()
            ->select([
                'content_id', 'SUM(read_num) read_num', 'SUM(like_num) like_num', 'SUM(collect_num) collect_num', 'SUM(comment_num) comment_num', 'COUNT(*) publish_num',
            ])
            ->where(['content_id' => $contentIds])
            ->groupBy('content_id')
            ->indexBy('content_id')
            ->asArray()
            ->all();
    }

    /**
     * 编辑发布内容
     * @param ContentPublishRecord $contentPublishRecord
     * @param ContentPublishRecordForm $model
     * @return ContentPublishRecord
     * @throws \Exception
     */
    public static function editModel(ContentPublishRecord $contentPublishRecord, ContentPublishRecordForm $model, ?Accounts $account = null): ContentPublishRecord
    {
        if ($model->getScenario() == 'create') {
            $contentPublishRecord->content_id = $model->content_id;
            $contentPublishRecord->doctor_id = $model->doctor_id;
            $contentPublishRecord->account_id = $account->id;
            $contentPublishRecord->created_member_id = Yii::$app->user->identity->member_id;
            $contentPublishRecord->change_date = DateHelper::timestampToDate(time());
            $contentPublishRecord->publish_time = strtotime($model->publish_time);
            $contentPublishRecord->operation_id = Yii::$app->user->identity->member_id;
            $contentPublishRecord->operation_name = Yii::$app->user->identity->member->realname;
        } elseif ($model->getScenario() == 'edit_data') {
            $contentPublishRecord->read_num = is_numeric($model->read_num) ? $model->read_num : null;
            $contentPublishRecord->like_num = is_numeric($model->like_num) ? $model->like_num : null;
            $contentPublishRecord->collect_num = is_numeric($model->collect_num) ? $model->collect_num : null;
            $contentPublishRecord->comment_num = is_numeric($model->comment_num) ? $model->comment_num : null;
        }
        $contentPublishRecord->saveAndCheckResult();

        return $contentPublishRecord;
    }

    /**
     * 发布内容
     * @param ContentPublishRecordForm $model
     * @return void
     */
    public function create(ContentPublishRecordForm $model): void
    {
        try {
            $transaction = Yii::$app->db->beginTransaction();

            foreach ($model->getAccountList() as $account) {
                // 1.新增发布内容
                $contentPublishRecord = new ContentPublishRecord();
                $contentPublishRecord = self::editModel($contentPublishRecord, $model, $account);
                // 2.日志
                LogMemberOpService::createContentPublishRecordLog($model, $contentPublishRecord, null, $account);
            }

            $transaction->commit();
            return;
        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * 更新发布内容数据
     * @param ContentPublishRecordForm $model
     * @return array
     */
    public function updateData(ContentPublishRecordForm $model): array
    {
        try {
            $transaction = Yii::$app->db->beginTransaction();

            // 1.更新发布内容数据
            $oldContentPublishRecord = new ContentPublishRecord();
            $oldContentPublishRecord->setAttributes($model->getContentPublishRecord()->getAttributes());
            $contentPublishRecord = self::editModel($model->getContentPublishRecord(), $model);
            // 2.日志
            if (LogMemberOpService::createContentPublishRecordLog($model, $contentPublishRecord, $oldContentPublishRecord)) {
                // 3.存在修改更新日期、操作人
                $contentPublishRecord->change_date = DateHelper::timestampToDate(time());
                $contentPublishRecord->operation_id = Yii::$app->user->identity->member_id;
                $contentPublishRecord->operation_name = Yii::$app->user->identity->member->realname;
                $contentPublishRecord->saveAndCheckResult();
            }
            $transaction->commit();
            return ['id' => $contentPublishRecord->id];
        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }

    /**
     * 删除内容数据
     * @param ContentPublishRecordForm $model
     * @return array
     */
    public function delete(ContentPublishRecordForm $model): array
    {
        try {
            $transaction = Yii::$app->db->beginTransaction();

            // 1.删除内容数据
            $contentPublishRecord = $model->getContentPublishRecord();
            $contentPublishRecord->status = ContentPublishRecord::STATUS_DELETE;
            $contentPublishRecord->operation_id = Yii::$app->user->identity->member_id;
            $contentPublishRecord->operation_name = Yii::$app->user->identity->member->realname;
            $contentPublishRecord->saveAndCheckResult();
            // 2.日志
            LogMemberOpService::createContentPublishRecordLog($model, $contentPublishRecord);
            $transaction->commit();
            return ['id' => $contentPublishRecord->id];
        } catch (\Exception $e) {
            $transaction->rollBack();
            throw $e;
        }
    }
}
